package com.letv.whatslive.mongo.dao;

import com.google.common.collect.Lists;
import com.letv.whatslive.common.utils.DateUtils;
import com.letv.whatslive.common.utils.ObjectUtils;
import com.letv.whatslive.model.Questionnaire;
import com.letv.whatslive.model.SubQuestionnaire;
import com.letv.whatslive.model.convert.QuestionnaireConvert;
import com.letv.whatslive.model.convert.SubQuestionnaireConvert;
import com.letv.whatslive.model.utils.ObjUtils;
import com.letv.whatslive.mongo.BaseDAO;
import com.letv.whatslive.redis.JedisDAO;
import com.mongodb.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 直播Collection操作DAO
 * Created by shenyue on 16-4-5.
 */
@Repository
public class QuestionnaireDAO extends BaseDAO {

    private final static Logger logger = LoggerFactory.getLogger(QuestionnaireDAO.class);

    protected String collectionName = "questionnaire";

    @Autowired
    protected JedisDAO jedisDAO;

    @Override
    protected void init() {
        super.init(this.collectionName);
    }

    @Override
    protected long getAutoIncrementId() {
        return idGenerate.generateId(this.collectionName);
    }

    public long insertQuestionnaire(Questionnaire questionnaire) {
        DBObject obj = QuestionnaireConvert.castQuestionnaireToDBObject(questionnaire);
        return this.insert(obj);
    }

    public Boolean insertSubQuestionnaire(Long questionnaireId,SubQuestionnaire subQuestionnaire) {
        if(questionnaireId==null)
            return false;
        if(subQuestionnaire==null)
            return false;
        Questionnaire questionnaire=getQuestionnaireById(questionnaireId);
        if(questionnaire==null)
            return false;
        Long newCount=questionnaire.getCount()+1;
        subQuestionnaire.setId(newCount);
        DBObject queryCondition = new BasicDBObject();
        queryCondition.put("_id", questionnaireId); // 用来确定要修改的文档
        BasicDBObject setValue = new BasicDBObject();
        setValue.put("count",newCount);
        BasicDBObject subquestionnaireDBObject = new BasicDBObject();
        subquestionnaireDBObject.put("subQuestionnaires", SubQuestionnaireConvert.castSubQuestionnaireToDBObject(subQuestionnaire));
        //剔除主键修改
        if (setValue.containsField("_id")) {
            setValue.removeField("_id");
        }
        DBObject updateValue = new BasicDBObject("$set", setValue);
        updateValue.put("$push", subquestionnaireDBObject);
        this.dbCollection.update(queryCondition, updateValue, true, false);
        return true;
    }


    public List<Questionnaire> getAllQuestionnaire(Integer start, Integer limit, Map<String, Object> params) {

        // // TODO 时移播放
//        params.put("status",1);
        DBObject order = new BasicDBObject();
        order.put("createTime", -1);
        List<DBObject> questionnaireList = selectAll(start, limit, params, order);
        List<Questionnaire> result = Lists.newArrayList();
        for (DBObject obj : questionnaireList) {
            Questionnaire questionnaire = QuestionnaireConvert.castDBObjectToQuestionnaire(obj);
            result.add(questionnaire);
        }
        return result;
    }


    /**
     * 查询视频列表
     *
     * @param orders 查询的排序条件
     * @param params 模糊查询的查询条件
     * @param start  查询条件的开始分页数
     * @param limit  查询条件的分页每页条数
     * @return
     */
    public List<Questionnaire> getQuestionnaireListByParams(Map<String, Object> orders, Map<String, Object> params, Integer start, Integer limit) {

        List<Questionnaire> result = Lists.newArrayList();
        if (limit == null) {
            limit = DEFAULT_NUM;
        }
        try {
            //dbObj 类似于 mysql 查询中的 where 关键字，可以添加各种搜索条件
            BasicDBObject query = getBasicDBObjectByParams(params);
            BasicDBObject order = getOrderParams(orders);
            Integer skip = start == null ? 0 : start;
            DBCursor cur = this.dbCollection.find(query).skip(skip)
                    .sort(order).limit(limit);//按照视频类型和创建时间倒序
            while (cur.hasNext()) {
                DBObject dbObject = cur.next();
                Questionnaire questionnaire = QuestionnaireConvert.castDBObjectToQuestionnaire(dbObject);
                setValueToQuestionnaire(questionnaire);
                result.add(questionnaire);
            }
        } catch (Exception e) {
            logger.error("", e);
        }
        return result;
    }

    public List<Long> getQuestionnaireIdsByParams(Map<String, Object> params, Map<String, Object> orders) {

        List<Long> result = Lists.newArrayList();
        try {
            //dbObj 类似于 mysql 查询中的 where 关键字，可以添加各种搜索条件
            BasicDBObject query = getBasicDBObjectByParams(params);
            BasicDBObject order = getOrderParams(orders);
            DBCursor cur = this.dbCollection.find(query).sort(order);
            while (cur.hasNext()) {
                DBObject dbObject = cur.next();
                result.add(ObjUtils.toLong(dbObject.get("_id")));
            }
        } catch (Exception e) {
            logger.error("", e);
        }
        return result;
    }


    /**
     * 查询直播的记录数
     *
     * @param params 查询条件参数
     * @return 满足条件的文档记录数
     */
    public Long countQuestionnaireByParams(Map params) {
        //dbObj 类似于 mysql 查询中的 where 关键字，可以添加各种搜索条件
        BasicDBObject query = getBasicDBObjectByParams(params);
        return this.dbCollection.count(query);
    }

    /**
     * 根据直播ID查询直播信息
     *
     * @param id
     * @return
     */
    public Questionnaire getQuestionnaireById(Long id) {
        DBObject dbObject = new BasicDBObject();
        dbObject.put("_id", id);
        DBObject result = dbCollection.findOne(dbObject);
        if (result == null) {
            return null;
        }
        Questionnaire questionnaire = QuestionnaireConvert.castDBObjectToQuestionnaire(result);
        setValueToQuestionnaire(questionnaire);
        return questionnaire;
    }

    /**
     * 更新直播信息
     *
     * @param questionnaire
     */
    public void updateQuestionnaire(Questionnaire questionnaire) {
        DBObject queryCondition = new BasicDBObject();
        Long pid = questionnaire.getId();
        queryCondition.put("_id", pid); // 用来确定要修改的文档
        BasicDBObject setValue = (BasicDBObject) QuestionnaireConvert.castQuestionnaireToDBObject(questionnaire);
        //剔除主键修改
        if (setValue.containsField("_id")) {
            setValue.removeField("_id");
        }
        DBObject updateValue = new BasicDBObject("$set", setValue);
        this.dbCollection.update(queryCondition, updateValue, true, false);
    }

    /**
     * 根据直播ID删除直播
     *
     * @param uid
     */
    public void deleteQuestionnaire(Long uid) {
        BasicDBObject query = new BasicDBObject();
        query.put("_id", uid);
        this.dbCollection.remove(query);
    }

    /**
     * 根据查询参数Map获取查询条件对象
     *
     * @param params 查询参数Map
     * @return
     */
    private BasicDBObject getBasicDBObjectByParams(Map params) {
        //dbObj 类似于 mysql 查询中的 where 关键字，可以添加各种搜索条件
        BasicDBObject query = new BasicDBObject();// 新建查询基类对象 dbo
        if (params != null && params.size() > 0) {
            if (params.get("id") != null) {
                query.put("_id", ObjectUtils.toLong(params.get("id")));
            }
            if (params.get("pFullName") != null) {
                query.put("name", params.get("pFullName"));
            }
            if (params.get("createTime_start") != null && params.get("createTime_start") != null) {
                query.put("createTime", new BasicDBObject("$gt",
                        ObjectUtils.toLong(params.get("createTime_start"))).append("$lte", ObjectUtils.toLong(params.get("createTime_start"))));

            }
            if (params.get("subQuestionnaires.id") != null) {
                query.put("subQuestionnaires.id", ObjectUtils.toLong(params.get("subQuestionnaires.id")));
            }
        }
        return query;
    }

    /**
     * 获取排序的BasicDBObject对象
     *
     * @param orders
     * @return
     */
    private BasicDBObject getOrderParams(Map<String, Object> orders) {
        BasicDBObject order = new BasicDBObject();
        if (null != orders && orders.size() > 0) {
            for (String key : orders.keySet()) {
                order.append(key, Integer.valueOf(String.valueOf(orders.get(key))));
            }
        } else {
            //默认按照创建时间排序
            order.append("createTime", -1);
        }
        return order;
    }

    /**
     * 设置直播信息中的特殊值
     *
     * @param questionnaire
     */
    private void setValueToQuestionnaire(Questionnaire questionnaire) {
        questionnaire.setCreateTimeStr(questionnaire.getCreateTime() != null ?
                DateUtils.long2YMDHMS(questionnaire.getCreateTime()) : "");
    }

    public List<Questionnaire> getAllQuestionnaireByParams(Map<String, Object> params) {
        List<Questionnaire> result = Lists.newArrayList();
        try {
            //dbObj 类似于 mysql 查询中的 where 关键字，可以添加各种搜索条件
            BasicDBObject query = getBasicDBObjectByParams(params);
            DBCursor cur = this.dbCollection.find(query);
            while (cur.hasNext()) {
                DBObject dbObject = cur.next();
                Questionnaire questionnaire = QuestionnaireConvert.castDBObjectToQuestionnaire(dbObject);
                setValueToQuestionnaire(questionnaire);
                result.add(questionnaire);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 解决内嵌集合里排序问题
     *
     * @param params
     * @param orders
     * @param start
     * @param limit
     * @return
     */
//    public List<Questionnaire> getQuestionnaireListByParamsUnwindCollection(Map<String, Object> params, Map<String, Object> orders, Integer start, Integer limit) {
//
//        List<Questionnaire> questionnaireList = Lists.newArrayList();
//        if (limit == null) {
//
//            limit = DEFAULT_NUM;
//        }
//
//        try {
//
//            List<DBObject> pipeline = Lists.newArrayList();
//
//            // 检索条件
//            BasicDBObject matchDBObj = new BasicDBObject();
//            BasicDBObject matchCondition = new BasicDBObject();
//
//            // id
//            if (params.get("id") != null) {
//                matchCondition.put("_id", ObjectUtils.toLong(params.get("id")));
//            }
//            // 名称
//            if (params.get("name") != null) {
//                BasicDBList values = new BasicDBList();
//                Pattern pattern = Pattern.compile("^.*" + params.get("name") + ".*$", Pattern.CASE_INSENSITIVE);
//                values.add(new BasicDBObject("_id", ObjectUtils.toLong(params.get("name"))));
//                values.add(new BasicDBObject("name", pattern));
//                matchCondition.put("$or", values);
//            }
//            // 问题id
//            if (params.get("subQuestionnaires.id") != null) {
//
//                matchCondition.put("subQuestionnaires.id", ObjectUtils.toLong(params.get("subQuestionnaires.id")));
//            }
//
//            matchDBObj.put("$match", matchCondition);
//            pipeline.add(matchDBObj);
//
//            // 展开条件
//            BasicDBObject unwindDBObj = new BasicDBObject();
//            unwindDBObj.put("$unwind", "$subQuestionnaires");
//            pipeline.add(unwindDBObj);
//
//            // 筛选条件
//            BasicDBObject secondMatchDBObj = new BasicDBObject();
//            BasicDBObject secondMatchCondition = new BasicDBObject();
//            if (params.get("subQuestionnaires.id") != null) {
//
//                secondMatchCondition.put("subQuestionnaires.id", ObjectUtils.toLong(params.get("subQuestionnaires.id")));
//            }
//            secondMatchDBObj.put("$match", secondMatchCondition);
//            pipeline.add(secondMatchDBObj);
//
//            // 排序
//            BasicDBObject sortDBObj = new BasicDBObject();
//            BasicDBObject sortCondition = new BasicDBObject();
//            // 优先级
//            if (orders.get("subQuestionnaires.priority") != null)
//                sortCondition.put("subQuestionnaires.priority", ObjectUtils.toLong(orders.get("subQuestionnaires.priority")));
//            sortDBObj.put("$sort", sortCondition);
//            pipeline.add(sortDBObj);
//
//            // 分页条件
//            BasicDBObject skipDBObj = new BasicDBObject();
//            skipDBObj.put("$skip", start);
//            pipeline.add(skipDBObj);
//            BasicDBObject limitDBObj = new BasicDBObject();
//            limitDBObj.put("$limit", limit);
//            pipeline.add(limitDBObj);
//            AggregationOutput output = this.dbCollection.aggregate(pipeline);
//            Iterator<DBObject> result = output.results().iterator();
//
//            while (result.hasNext()) {
//
//                DBObject dbObject = result.next();
//                Questionnaire questionnaire = QuestionnaireConvert.castDBObjectToQuestionnaire(dbObject);
//                questionnaireList.add(questionnaire);
//            }
//
//        } catch (Exception e) {
//            logger.error(e.getMessage(), e);
//        }
//        return questionnaireList;
//    }

}
